home *** CD-ROM | disk | FTP | other *** search
/ NeXTSTEP 3.1 (Developer) [x86] / NeXT Step 3.1 Intel dev.cdr.dmg / NextDeveloper / Headers / kernserv / i386 / spl_lock.h next >
Encoding:
C/C++ Source or Header  |  1993-04-30  |  2.3 KB  |  110 lines

  1. /* Copyright (c) 1992 NeXT Computer, Inc.  All rights reserved.
  2.  * 
  3.  *    File:    kernserv/i386/spl_lock.h
  4.  *
  5.  *    Multiprocessor safe simple lock with spl support.
  6.  *
  7.  *    This implementation is actually    machine independent; it is
  8.  *     in the nrw directory to keep it out of the 3.0 release. Post 
  9.  *    3.0 this file should probably be in kernserv/spl_lock.h.
  10.  *
  11.  * HISTORY
  12.  * 29-Jan-92    Doug Mitchell at NeXT
  13.  *    Created.
  14.  */
  15.  
  16. #ifndef    _KERNSERV_I386_SPL_LOCK_
  17. #define _KERNSERV_I386_SPL_LOCK_
  18.  
  19. #import <mach/machine/simple_lock.h>
  20. #import <bsd/machine/spl.h>
  21. #import <kernserv/kalloc.h>
  22.  
  23. /*
  24.  * Encapsulation of a simple lock and its associated IPL. On a multi, 
  25.  * every instance of spln() needs to be paired with a simple_lock() in
  26.  * to provide protection from accesses by other CPUs. The spl_lock_t type
  27.  * provides a means of associating an instance of simple_lock with
  28.  * the IPL which must be set to provide adequate protection.
  29.  */
  30. typedef struct {
  31.     simple_lock_data_t     lock;
  32.     unsigned         min_ipl;
  33. } spl_lock_t;
  34.  
  35. /*
  36.  * Allocate and free spl_lock_t's.
  37.  */
  38. static inline spl_lock_t *
  39. spl_lock_alloc()
  40. {
  41.     return ((spl_lock_t *)kalloc(sizeof(spl_lock_t)));
  42. }
  43.  
  44. static inline void 
  45. spl_lock_free(spl_lock_t *lock)
  46. {
  47.     kfree(lock, sizeof(spl_lock_t));
  48. }
  49.  
  50. /*
  51.  * Initialize an spl_lock_t.
  52.  */
  53. static inline void 
  54. spl_lock_init(spl_lock_t *lock, unsigned min_ipl)
  55. {
  56.     simple_lock_init(&lock->lock);
  57.     lock->min_ipl = min_ipl;
  58. }
  59.  
  60. /*
  61.  * Set ipl to appropriate level and acquire lock. Returns an spl to be
  62.  * used subsequently with spl_unlock().
  63.  */
  64. static inline unsigned 
  65. spl_lock(spl_lock_t *lock)
  66. {
  67.     unsigned rtn;
  68.     
  69.     if(curipl() >= lock->min_ipl) {
  70.         /*
  71.          * Don't have to change ipl; just get current value.
  72.          */
  73.         rtn = curipl();
  74.     }
  75.     else {
  76.         rtn = spln(ipltospl(lock->min_ipl));
  77.     }
  78.     simple_lock(&lock->lock);
  79.     return rtn;
  80. }
  81.  
  82. /*
  83.  * Release lock, return to previous spl.
  84.  */
  85. static inline void 
  86. spl_unlock(spl_lock_t *lock, unsigned new_spl)
  87. {
  88.     simple_unlock(&lock->lock);
  89.     splx(new_spl);
  90. }
  91.  
  92. /*
  93.  * Version of thread_sleep() using spl_lock_t instead of simple_lock_t.
  94.  * Used while holding lock and about to sleep. 
  95.  */
  96. static inline void 
  97. spl_lock_thread_sleep(
  98.     int event, 
  99.     spl_lock_t *lock, 
  100.     boolean_t interruptible,
  101.     unsigned new_spl)
  102. {
  103.     void        thread_sleep();
  104.     
  105.     thread_sleep(event, &lock->lock, interruptible);
  106.     splx(new_spl);
  107. }
  108.  
  109. #endif    _KERNSERV_I386_SPL_LOCK_
  110.